import 'package:flutter/material.dart';
import 'dart:async';

class MDTypewriterText extends StatefulWidget {
  final TextSpan textSpan;
  final Duration duration;
  final bool needType;
  final Function onComplete;
  final Function onLineBreak;

  const MDTypewriterText({
    Key? key,
    required this.textSpan,
    this.needType = true,
    required this.onComplete,
    required this.onLineBreak,
    this.duration = const Duration(milliseconds: 50),
  }) : super(key: key);

  @override
  _MDTypewriterTextState createState() => _MDTypewriterTextState();
}

class _MDTypewriterTextState extends State<MDTypewriterText> with AutomaticKeepAliveClientMixin{
  String _displayText = '';
  int _currentIndex = 0;
  Timer? _timer;

  @override
  void initState() {
    super.initState();
    if(widget.needType){
      _startTypewriter();
    }else{
      setState(() {
        _displayText = _getTextFromTextSpan(widget.textSpan);
      });
    }
  }

  void _startTypewriter() {
    _timer = Timer.periodic(widget.duration, (timer) {
      final text = _getTextFromTextSpan(widget.textSpan);
      if (_currentIndex < text.length) {
        setState(() {
          _displayText += text[_currentIndex];
          _currentIndex++;
          _checkLineBreak(); // 检查是否换行
        });
      } else {
        widget.onComplete();
        timer.cancel();
      }
    });
  }


  void _checkLineBreak() {
    final textPainter = TextPainter(
      text: TextSpan(text: _displayText, style: widget.textSpan.style),
      textDirection: TextDirection.ltr,
    );
    textPainter.layout(maxWidth: MediaQuery.of(context).size.width);

    final textHeight = textPainter.size.height;
    if (textHeight > widget.textSpan.style!.fontSize!) {
      widget.onLineBreak(); // 触发换行回调
    }
  }

  String _getTextFromTextSpan(TextSpan textSpan) {
    String text = '';
    void visitTextSpan(TextSpan span) {
      text += span.text ?? '';
      for (var child in span.children ?? []) {
        visitTextSpan(child);
      }
    }
    visitTextSpan(textSpan);
    return text;
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text.rich(
      TextSpan(
        style: widget.textSpan.style,
        children: [
          TextSpan(text: _displayText),
        ],
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;
}
